﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Windows.Forms;
using RestaurateurConsole;
using RestaurateurConsole.Core;

namespace RestaurateurGUI
{
    public partial class MainForm : Form
    {
        static Restaurateur DB;
        public static Form creatorForm = null;
        DishesHandler dishesHandler;
        CustomerHandler accountHandler;
        ActivityHandler activityHandler;
        SalesHandler salesHandler;
        SoldItemsHandler soldItemsHandler;

        public static Form CreatorForm
        {
            get
            {
                return creatorForm;
            }
            set
            {
                creatorForm = value;
            }
        }

        ToolStripTextBox toolStripTextBox3 = new ToolStripTextBox();

        private MainForm() { }

        public MainForm(DishesHandler dishesHandler, CustomerHandler accountHandler, ActivityHandler activityHandler, SalesHandler salesHandler, SoldItemsHandler soldItemsHandler, Restaurateur DB)
        {
            MainForm.DB = DB;
            this.dishesHandler = dishesHandler;
            this.accountHandler = accountHandler;
            this.activityHandler = activityHandler;
            this.salesHandler = salesHandler;
            this.soldItemsHandler = soldItemsHandler;
            InitializeComponent();
            InitializeViews();
            tabControl1.SelectedTab = tabControl1.TabPages[3];
        }

        private void InitializeViews()
        {
            listView1.DoubleClick += new EventHandler(listView1_DoubleClick);
            label10.Text = String.Format("Tax (@{0}%):", ConfigHandler.Configuration.TaxRate);
            splitContainer1.SplitterDistance = 350;
            labelAmtWithoutTax.Text = labelNoOfItems.Text = labelAmtWithTax.Text = labelTax.Text = label4.Text = label5.Text = label3.Text = statusText.Text = "";
            
            InitializeMenu();
            InitializeAccount();
            InitializeSales();
            InitializeBill();
            InitBalance();
            PopulateSalesDetailsGrid();
            PopulateBillMenuGrid();
        }

        void listView1_DoubleClick(object sender, EventArgs e)
        {
            billmenuGrid_CellDoubleClick(listView1.SelectedItems[0].Text, false);
        }

        void billmenuGrid_CellDoubleClick(string Name, bool NonMenuItem)
        {
            if (billGrid.Enabled)
            {
                if (billGrid.Rows[billGrid.Rows.Count - 1].Cells[0].Value as string == "")
                    billGrid.Rows.Add();
                if (NonMenuItem)
                    billGrid.Rows[billGrid.Rows.Count - 1].Cells[4].Value = Name;
                else
                    billGrid.Rows[billGrid.Rows.Count - 1].Cells[0].Value = Name;
                billGrid.Select();
            }
        }

        PerTableBill[] perTableBill = new PerTableBill[ConfigHandler.Configuration.NoOfTables];
        int currentTable = -1;
        
        private void toolStripButton9_Click(object sender, EventArgs e)
        {
            SaveOpenBill(true);
        }

        private void SaveOpenBill(bool Print)
        {
            Control eCtrl = billGrid.EditingControl;
            if (eCtrl != null)
            {
                eCtrl.Enabled = false;
                billGrid_CellEndEdit(billGrid, new DataGridViewCellEventArgs(0, billGrid.Rows.Count - 1));
                eCtrl.Enabled = true;
            }
            
            int BillID = -1;
            if (billGrid.Enabled)
            {
                try
                {
                    BillID = SaveBill(currentTable);
                    if (BillID == -1)
                        return;
                    if (Print)
                    {
                        PerTableBill bill = perTableBill[currentTable - 1];
                        PrintBill printForm = new PrintBill(bill.Bill.AsEnumerable(), BillID, bill.Account);
                        printForm.Print();
                    }
                    (billButtonsLayoutPanel.Controls[currentTable - 1] as Button).Text = currentTable.ToString() + "*";
                    perTableBill[currentTable - 1] = null;
                    currentTable = -1;
                    billGrid.Enabled = false;
                    billDate.Enabled = false;
                }
                catch (IndexOutOfRangeException x)
                {
                    statusText.Text = x.Message;
                    return;
                }
            }
        }

        private void toolStripButton7_Click(object sender, EventArgs e)
        {
            SaveOpenBill(false);
        }

        private void toolStripButton8_Click(object sender, EventArgs e)
        {
            if (billGrid.Enabled)
            {
                try
                {
                    (billButtonsLayoutPanel.Controls[currentTable - 1] as Button).Text = currentTable.ToString() + "*";
                    if (!ConfigHandler.Configuration.UnusedSalesID.Contains(perTableBill[currentTable - 1].BillNo))
                    {
                        var v = from salle in salesHandler.Sales
                                where salle.SalesID == perTableBill[currentTable - 1].BillNo
                                select salle;

                        if (v.Count() == 0)
                        {
                            ConfigHandler.Configuration.UnusedSalesID.Push(perTableBill[currentTable - 1].BillNo);
                            ConfigHandler.Configuration.Save();
                        }
                    }
                    perTableBill[currentTable - 1] = null;
                    currentTable = -1;
                    billGrid.Enabled = false;
                    billDate.Enabled = false;
                }
                catch (IndexOutOfRangeException x)
                {
                    statusText.Text = x.Message;
                }
            }
        }

        private int SaveBill(int currentTable)
        {
            int salesID = -1;
            bool SaveSalesAndCustomer = true;
            PerTableBill bill;
            if (currentTable == -1)
                return -1; ;
            try
            {
                SaveCurrentBillingSession();
                bill = perTableBill[currentTable - 1];
                if (bill.TotalWithoutTax == (decimal)0)
                {
                    MessageBox.Show("No item added to the bill, please add items or discard the bill.");
                    return -1;
                }
                if (bill.DirtySoldItemIDs.Count > 0)
                {
                    SaveSalesAndCustomer = false;
                    foreach (var v in bill.DirtySoldItemIDs)
                    {
                        soldItemsHandler.RemoveDeferred(v);
                    }
                    soldItemsHandler.Commit();
                }
                {
                    //First, save the sale (i.e., the bill).
                    if (SaveSalesAndCustomer)
                        salesID = salesHandler.Add(bill.BillNo, bill.TotalWithTax, bill.BillDate, bill.Account.ToLower());
                    else
                    {
                        salesID = bill.BillNo;
                        salesHandler.Edit(salesID, bill.TotalWithTax, bill.Account.ToLower());
                        activityHandler.Edit(salesID, bill.TotalWithTax, bill.Amount, bill.Account.ToLower());
                    }
                    soldItemsHandler.Add(from aB in bill.Bill
                                         select new SoldItem()
                                             {
                                                 SalesID = salesID,
                                                 SoldItemsID = ConfigHandler.Configuration.GetNewSoldItemsID(),
                                                 ItemName = String.IsNullOrEmpty(aB.OtherItem) ? aB.Item : aB.OtherItem,
                                                 Price = aB.Amount,
                                                 Quantity = (int)aB.Quantity
                                             });
                    ConfigHandler.Configuration.Save();
                    
                    //Deal with the activities now.
                    try
                    {
                        if (!String.IsNullOrEmpty(bill.Account))
                        {
                            var splitted = bill.Account.IndexOf("+") == -1 ? new[] { bill.Account } : bill.Account.Split('+');
                            foreach (var s in splitted)
                            {
                                int? custID = null;
                                try
                                {
                                    custID = accountHandler.Customers.First(C => C.CustomerName.ToLower() == s.ToLower()).CustomerID;
                                }
                                catch
                                {
                                    custID = accountHandler.Add(s);
                                }
                                if (custID == null)
                                    continue;
                                decimal? paid;
                                if (bill.Amount == (decimal)0)
                                    paid = null;
                                else
                                    paid = bill.Amount;
                                if (SaveSalesAndCustomer)
                                    activityHandler.Add(custID.Value, salesID, paid, bill.TotalWithTax / (decimal)splitted.Length, bill.BillDate);
                                else if ((from act in activityHandler.Activities where act.CustID == custID.Value && act.SalesID == salesID select act).Count() == 0)
                                    activityHandler.Add(custID.Value, salesID, paid, bill.TotalWithTax / (decimal)splitted.Length, bill.BillDate);
                            }
                            PopulateActivitiesGrid(currentUserID);
                        }
                    }
                    catch (Exception x)
                    {
                        statusText.Text = x.Message;
                    }
                }
            }
            catch (IndexOutOfRangeException x)
            {
                statusText.Text = x.Message;
                return salesID;
            }
            bill.IsSaved = true;
            PopulateAccountsGrid();
            PopulateSalesDetailsGrid();
            PopulateSalesGrid(false, null, "");
            return salesID;
        }

        private void AddColumnsToBillGrid()
        {
            DataGridViewComboBoxColumn itemColumn = new DataGridViewComboBoxColumn();
            itemColumn.Name = "Item";
            itemColumn.Width = 200;
            foreach (var item in dishesHandler.Dishes)
                itemColumn.Items.Add(item.DishName);

            billGrid.Columns.Clear();
            billGrid.Columns.Add(itemColumn);
            billGrid.Columns.Add(new DataGridViewTextBoxColumn() { Name = "Quantity" });
            billGrid.Columns.Add(new DataGridViewTextBoxColumn() { Name = "Price (Rs)" });
            billGrid.Columns.Add(new DataGridViewTextBoxColumn() { Name = "Amount (Rs)" });
        }

        private void InitializeBill()
        {
            billGrid.MultiSelect = false;
            AddColumnsToBillGrid();

            billGrid.Enabled = false;
            billDate.Enabled = false;
            billGrid.CellEndEdit += new DataGridViewCellEventHandler(billGrid_CellEndEdit);

            for (int i = 0; i < ConfigHandler.Configuration.NoOfTables; ++i)
            {
                Button b = new Button() { Height = 35, Width = 35, Text = (i + 1).ToString() + "*" };
                b.Click += new EventHandler(b_Click);
                billButtonsLayoutPanel.Controls.Add(b);
            }
        }

        void billGrid_CellEndEdit(object sender, DataGridViewCellEventArgs e)
        {
            if (sender == null)
            {
                try
                {
                    PerTableBill bill = perTableBill[currentTable - 1];
                    bill.NoOfItems = 0;
                    bill.TotalWithoutTax = (decimal)0;
                    labelNoOfItems.Text = bill.NoOfItems.ToString(); ;
                    labelAmtWithoutTax.Text = bill.TotalWithoutTax.ToString();
                    labelTax.Text = bill.Tax.ToString();
                    labelAmtWithTax.Text = bill.TotalWithTax.ToString();
                }
                catch (IndexOutOfRangeException x)
                {
                    statusText.Text = x.Message;
                }
                return;
            }
            if (e.ColumnIndex == 0 || e.ColumnIndex == 1)
            {
                DataGridViewComboBoxCell selection = billGrid[0, e.RowIndex] as DataGridViewComboBoxCell;
                string name = selection.Value as string;
                if (String.IsNullOrEmpty(name))
                    return;
                try
                {
                    if (billGrid[1, e.RowIndex].Value == null)
                        billGrid[1, e.RowIndex].Value = (decimal)1;
                }
                catch
                {
                    billGrid[1, e.RowIndex].Value = (decimal)1;
                }
                try
                {
                    billGrid[2, e.RowIndex].Value = dishesHandler.Dishes.First(D => D.DishName == name).DishPrice;
                }
                catch { }
            }
            
            decimal amt = (decimal)0;
            decimal quantity = 1, price = 1;
            try
            {
                try
                {
                    quantity = (decimal)billGrid[1, e.RowIndex].Value;
                }
                catch
                {
                    try
                    {
                        quantity = Decimal.Parse(billGrid[1, e.RowIndex].Value as string);
                        billGrid[1, e.RowIndex].Value = quantity;
                    }
                    catch (Exception x)
                    {
                        statusText.Text = x.Message;
                        return;
                    }
                }
                try
                {
                    price = (decimal)billGrid[2, e.RowIndex].Value;
                }
                catch
                {
                    try
                    {
                        price = Decimal.Parse(billGrid[2, e.RowIndex].Value as string);
                        billGrid[2, e.RowIndex].Value = price;
                    }
                    catch (Exception x)
                    {
                        statusText.Text = x.Message;
                        return;
                    }
                }
            }
            catch (ArgumentNullException x)
            {
                statusText.Text = x.Message;
            }
            
            amt = quantity * price;
            billGrid[3, e.RowIndex].Value = amt;
            decimal totalPrice = 0;
            
            for (int i = 0; i < billGrid.Rows.Count - 1; ++i)
            {
                try
                {
                    totalPrice += (decimal)billGrid[3, i].Value;
                }
                catch (Exception x)
                {
                    statusText.Text = x.Message;
                }
            }
            
            try
            {
                PerTableBill bill = perTableBill[currentTable - 1];
                bill.NoOfItems = billGrid.Rows.Count - 1;
                bill.TotalWithoutTax = totalPrice;
                labelNoOfItems.Text = bill.NoOfItems.ToString(); ;
                labelAmtWithoutTax.Text = bill.TotalWithoutTax.ToString();
                labelTax.Text = bill.Tax.ToString();
                labelAmtWithTax.Text = bill.TotalWithTax.ToString();
            }
            catch (IndexOutOfRangeException x)
            {
                statusText.Text = x.Message;
                return;
            }
        }

        void SaveCurrentBillingSession()
        {
            try
            {
                PerTableBill bill = perTableBill[currentTable - 1];
                bill.Bill.Clear();
                
                for (int i = 0; i < billGrid.Rows.Count - 1; ++i)
                {
                    if ((decimal)billGrid[1, i].Value == 0)
                        continue;
                    bill.Bill.Add(new ABill()
                    {
                        Item = billGrid[0, i].Value as string,
                        Quantity = (decimal)billGrid[1, i].Value,
                        Price = (decimal)billGrid[2, i].Value,
                        Amount = (decimal)billGrid[3, i].Value,
                        OtherItem = ""
                    });
                }
                
                bill.Account = textBox1.Text;
                
                try
                {
                    bill.Amount = Decimal.Parse(textBox2.Text);
                }
                catch
                {
                    bill.Amount = (decimal)0;
                }
            }
            catch (IndexOutOfRangeException x)
            {
                statusText.Text = x.Message;
                return;
            }
        }

        void b_Click(object sender, EventArgs e)
        {
            try
            {
                if (!billGrid.Enabled)
                {
                    //Start a new billing session.
                    billGrid.Enabled = true;
                    billDate.Enabled = true;
                }
                else
                {
                    //Save the current billing session before starting a new one.
                    SaveCurrentBillingSession();
                }
                
                Button senderButton = sender as Button;
                if (senderButton.Text.EndsWith("*"))
                    senderButton.Text = senderButton.Text.Substring(0, senderButton.Text.Length - 1);
                currentTable = Int32.Parse(senderButton.Text);

                if (perTableBill[currentTable - 1] == null)
                {
                    //If no bill was previously opened for the current table, only then create a new one. Or
                    //else use the already opened bill.
                    int newBillNo = ConfigHandler.Configuration.GetNewSalesID();

                    //Make sure the bill number isn't already existing.
                    while (true)
                    {
                        var v = from sale in DB.Sales
                                where sale.SalesID == newBillNo
                                select sale;
                        if (v.Count() == 0)
                            break;
                        newBillNo = ConfigHandler.Configuration.GetNewSalesID();
                    }
                    perTableBill[currentTable - 1] = new PerTableBill(currentTable) { BillNo = newBillNo };
                    ConfigHandler.Configuration.Save();
                }
                PopulateBillGrid();
            }
            catch (Exception x)
            {
                statusText.Text = x.Message;
            }
        }

        private void PopulateBillMenuGrid()
        {
            IEnumerable<Dish> dishes;
            if (billmenuFilter.Text == "")
                dishes = dishesHandler.Dishes;
            else
                dishes = dishesHandler.Filter(billmenuFilter.Text);

            listView1.Items.Clear();
            foreach (var v in dishes)
                listView1.Items.Add(new ListViewItem() { Text = v.DishName });
        }

        private void PopulateBillGrid()
        {
            PopulateBillMenuGrid();
            try
            {
                PerTableBill bill = perTableBill[currentTable - 1];
                billGrid.Rows.Clear();

                int i = 0;
                foreach (var aBill in bill.Bill)
                {
                    billGrid.Rows.Add();
                    billGrid.Rows[i++].SetValues(new object[]
                {
                    aBill.Item,
                    aBill.Quantity,
                    aBill.Price,
                    aBill.Amount,
                });
                }

                labelNoOfItems.Text = bill.NoOfItems.ToString(); ;
                labelAmtWithoutTax.Text = bill.TotalWithoutTax.ToString();
                labelTax.Text = bill.Tax.ToString();
                labelAmtWithTax.Text = bill.TotalWithTax.ToString();
                textBox1.Text = bill.Account;
                textBox2.Text = bill.Amount.ToString();
                billDate.Value = bill.BillDate;
                label11.Text = "Bill Number: " + bill.BillNo.ToString();
            }
            catch (IndexOutOfRangeException x)
            {
                statusText.Text = x.Message;
            }
        }

        private void InitializeSales()
        {
            salesGrid.Columns.Add(new DataGridViewTextBoxColumn() { Name = "SalesID" });
            salesGrid.Columns.Add(new DataGridViewTextBoxColumn() { Name = "Date" });
            salesGrid.Columns.Add(new DataGridViewTextBoxColumn() { Name = "Amount" });
            salesGrid.Columns.Add(new DataGridViewTextBoxColumn() { Name = "Account" });

            toolStripTextBox3.TextChanged += new EventHandler(toolStripTextBox3_TextChanged);
            textBox3.Text = "Click here to search for sales credited to accounts...";
            textBox3.Click += new EventHandler(textBox3_Click);

            radioButton1.CheckedChanged += new EventHandler(radioButton1_CheckedChanged);
            radioButton2.CheckedChanged += new EventHandler(radioButton2_CheckedChanged);
            dateTimePicker2.ValueChanged += new EventHandler(dateTimePicker2_ValueChanged);
            
            salesGrid.DoubleClick += new EventHandler(salesGrid_DoubleClick);
            salesFilter.CheckStateChanged += new EventHandler(salesFilter_CheckStateChanged);
            
            comboBox1.SelectedIndexChanged += new EventHandler(comboBox1_SelectedIndexChanged);
            numericUpDown1.ValueChanged += new EventHandler(numericUpDown1_ValueChanged);

            radioButton2.Checked = true;
            radioButton1.Checked = false;
            dateTimePicker2.Value = DateTime.Now;

            numericUpDown1.Minimum = (decimal)2000;
            numericUpDown1.Maximum = (decimal)DateTime.Now.Year;
            numericUpDown1.Value = (decimal)DateTime.Now.Year;

            comboBox1.AutoCompleteMode = AutoCompleteMode.Append;
            comboBox1.SelectedIndex = DateTime.Now.Month - 1;
            
            salesFilter.Checked = true;

            salesGrid.SelectionChanged += new EventHandler(salesGrid_SelectionChanged);
            salesDetailsGrid.DoubleClick += new EventHandler(doubleClick_salesDetailsGrid);
            PopulateSalesGrid(false, null, "");
        }

        void textBox3_Click(object sender, EventArgs e)
        {
            textBox3.SelectAll();
        }

        void toolStripTextBox3_TextChanged(object sender, EventArgs e)
        {
            if (toolStripTextBox3.Text == "")
                PopulateSalesGrid(false, null, "");
            else
                PopulateSalesGrid(false, null, toolStripTextBox3.Text);
        }

        void dateTimePicker2_ValueChanged(object sender, EventArgs e)
        {
            PopulateSalesGrid(false, null, "");
        }

        void radioButton2_CheckedChanged(object sender, EventArgs e)
        {
            PopulateSalesGrid(false, null, "");
        }

        void radioButton1_CheckedChanged(object sender, EventArgs e)
        {
            PopulateSalesGrid(false, null, "");
        }

        void salesGrid_DoubleClick(object sender, EventArgs e)
        {
            editBillToolStripMenuItem_Click(null, null);
        }

        void numericUpDown1_ValueChanged(object sender, EventArgs e)
        {
            PopulateSalesGrid(false, null, "");
        }

        void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            PopulateSalesGrid(false, null, "");
        }

        void salesFilter_CheckStateChanged(object sender, EventArgs e)
        {
            PopulateSalesGrid(false, null, "");
        }

        void doubleClick_salesDetailsGrid(object sender, EventArgs e)
        {
            List<ABill> salesDetails = new List<ABill>();
            for (int i = 0; i < salesDetailsGrid.Rows.Count; ++i)
            {
                ABill nB = new ABill()
                {
                    Item = salesDetailsGrid[1, i].Value as string,
                    Quantity = (int)salesDetailsGrid[3, i].Value,
                    Amount = (decimal)salesDetailsGrid[4, i].Value
                };
                nB.Price = nB.Amount / (decimal)nB.Quantity;
                salesDetails.Add(nB);
            }
            
            PrintBill printForm = new PrintBill(salesDetails.AsEnumerable(), (int)salesDetailsGrid.SelectedRows[0].Cells["SalesID"].Value, "");
            if (sender != null)
                printForm.ShowDialog();
            else
                printForm.Print();
        }

        void salesGrid_SelectionChanged(object sender, EventArgs e)
        {
            PopulateSalesDetailsGrid();
        }

        private void PopulateSalesGrid(bool ShowTodaysSales, int? SalesID, string SearchAccount)
        {
            IEnumerable<Sale> sales;
            if (SalesID.HasValue)
            {
                sales = salesHandler.GetBillForSalesID(SalesID.Value);
            }
            else if (ShowTodaysSales)
            {
                sales = salesHandler.FilterTodays();
            }
            else if (!String.IsNullOrEmpty(SearchAccount))
            {
                sales = salesHandler.SearchAccount(SearchAccount);
            }
            else if (!salesFilter.Checked)
                sales = salesHandler.Sales;
            else
            {
                if (radioButton1.Checked)
                {
                    if (comboBox1.SelectedIndex < 0 || comboBox1.SelectedIndex > 11)
                    {
                        statusText.Text = "Invalid value specified for the month. Cannot filter.";
                        salesFilter.Checked = false;
                        return;
                    }
                    sales = salesHandler.Filter(new DateTime((int)numericUpDown1.Value, comboBox1.SelectedIndex + 1, 1));
                }
                else
                {
                    sales = salesHandler.FilterOneDay(dateTimePicker2.Value);
                }
            }

            salesGrid.Rows.Clear();
            int lastSalesID = -1;
            DateTime lastD = DateTime.Now;
            
            foreach (var v in sales)
            {
                if (lastSalesID != -1 && String.IsNullOrEmpty(SearchAccount))
                {
                    //Make sure bills aren't skipped.
                    while (++lastSalesID < v.SalesID)
                    {
                        salesGrid.Rows.Add(new object[] { lastSalesID, lastD, (decimal)0, "" });
                    }
                }
                lastD = v.Date;
                lastSalesID = v.SalesID;
                salesGrid.Rows.Add(new object[] { v.SalesID, v.Date, v.Amount, v.Account });
            }

            decimal totalSales = (decimal)0;
            decimal creditSales = (decimal)0;
            for (int i = 0; i < salesGrid.Rows.Count; ++i)
            {
                totalSales += (decimal)salesGrid[2, i].Value;
                if (!String.IsNullOrEmpty(salesGrid[3, i].Value as string))
                    creditSales += (decimal)salesGrid[2, i].Value;
            }
            
            label13.Text = String.Format("Sales: Rs {0}; Credit: Rs {1}; Cash: Rs {2}", totalSales, creditSales, totalSales - creditSales);
        }

        private void PopulateSalesDetailsGrid()
        {
            IEnumerable<SoldItem> soldItems;
            if (salesGrid.SelectedRows.Count == 0)
            {
                salesDetailsGrid.Rows.Clear();
                return;
            }
            else
                soldItems = soldItemsHandler.Filter((int)salesGrid.SelectedRows[0].Cells[0].Value);

            if (salesDetailsGrid.Rows.Count > 0)
                salesDetailsGrid.Rows.Clear();
            if (salesDetailsGrid.Columns.Count > 0)
                salesDetailsGrid.Columns.Clear();
            
            salesDetailsGrid.Columns.Add(new DataGridViewTextBoxColumn() { Name = "SalesID" });
            salesDetailsGrid.Columns.Add(new DataGridViewTextBoxColumn() { Name = "ItemName" });
            salesDetailsGrid.Columns.Add(new DataGridViewTextBoxColumn() { Name = "Rate" });
            salesDetailsGrid.Columns.Add(new DataGridViewTextBoxColumn() { Name = "Quantity" });
            salesDetailsGrid.Columns.Add(new DataGridViewTextBoxColumn() { Name = "Amount" });
            salesDetailsGrid.Columns.Add(new DataGridViewTextBoxColumn() { Name = "SoldItemsID" });

            foreach (var s in soldItems)
            {
                DataGridViewRow row = new DataGridViewRow();
                row.Cells.Add(new DataGridViewTextBoxCell() { Value = s.SalesID });
                row.Cells.Add(new DataGridViewTextBoxCell() { Value = s.ItemName });
                row.Cells.Add(new DataGridViewTextBoxCell() { Value = s.Price / s.Quantity });
                row.Cells.Add(new DataGridViewTextBoxCell() { Value = s.Quantity });
                row.Cells.Add(new DataGridViewTextBoxCell() { Value = s.Price });
                row.Cells.Add(new DataGridViewTextBoxCell() { Value = s.SoldItemsID });
                
                salesDetailsGrid.Rows.Add(row);
            }
        }


        private void InitializeAccount()
        {
            dateTimePicker1.Value = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);
            filterAccountActivities.Checked = true;
            accountActivitiesGrid.DoubleClick += new EventHandler(salesDetailsGrid_DoubleClick);
            filterAccountActivities.CheckedChanged += new EventHandler(filterAccountActivities_CheckedChanged);
            dateTimePicker1.ValueChanged += new EventHandler(dateTimePicker1_ValueChanged);
            toolStripTextBox2.TextChanged += new EventHandler(toolStripTextBox2_TextChanged);
            tabControl1.Selected += new TabControlEventHandler(tabControl1_Selected);
            accountsGrid.MultiSelect = false;
            accountsGrid.SelectionChanged += new EventHandler(accountsGrid_SelectionChanged);
            PopulateAccountsGrid();
        }

        void salesDetailsGrid_DoubleClick(object sender, EventArgs e)
        {
            if (accountActivitiesGrid.SelectedRows.Count == 0)
                return;
            try
            {
                int salesID = (int)accountActivitiesGrid.SelectedRows[0].Cells["SalesID"].Value;
                var data = from s in soldItemsHandler.Filter(salesID)
                           select new ABill()
                           {
                               Item = s.ItemName,
                               Amount = s.Price,
                               Quantity = (int)s.Quantity,
                               Price = s.Price / (decimal)s.Quantity
                           };
                PrintBill printForm = new PrintBill(data, (int)accountActivitiesGrid.SelectedRows[0].Cells["SalesID"].Value, null);
                if (sender != null)
                    printForm.ShowDialog();
                else
                    printForm.Print();
            }
            catch
            {
                statusText.Text = "No bill was associated with the current purchase.";
            }
        }

        void filterAccountActivities_CheckedChanged(object sender, EventArgs e)
        {
            PopulateActivitiesGrid(currentUserID);
        }

        void dateTimePicker1_ValueChanged(object sender, EventArgs e)
        {
            PopulateActivitiesGrid(currentUserID);
        }

        void toolStripTextBox2_TextChanged(object sender, EventArgs e)
        {
            PopulateAccountsGrid();
        }

        void tabControl1_Selected(object sender, TabControlEventArgs e)
        {
            if (e.TabPage.Text == "Accounts" && accountsGrid.Rows.Count > 0)
                accountsGrid.Rows[0].Selected = true;
        }

        void accountsGrid_SelectionChanged(object sender, EventArgs e)
        {
            if (accountsGrid.SelectedRows.Count == 0) 
                return;
            int accountID = (int)accountsGrid.SelectedRows[0].Cells["CustomerID"].Value;
            if (accountID != 0)
                PopulateActivitiesGrid(accountID);
        }

        int currentUserID;
        private void PopulateActivitiesGrid(int accountID)
        {
            currentUserID = accountID;
            IEnumerable<Activity> acts;
            if (!filterAccountActivities.Checked)
                acts = activityHandler.Filter(accountID);
            else
                acts = activityHandler.Filter(accountID, dateTimePicker1.Value);
            accountActivitiesGrid.DataSource = acts;

            decimal sales = (decimal)0;
            decimal payments = (decimal)0;
            for (int i = 0; i < accountActivitiesGrid.Rows.Count; ++i)
            {
                try
                {
                    sales += (decimal)accountActivitiesGrid.Rows[i].Cells["Purchase"].Value;
                }
                catch { }
                try
                {
                    payments += (decimal)accountActivitiesGrid.Rows[i].Cells["Payment"].Value;
                }
                catch { }
            }

            label4.Text = String.Format("Rs {0}.", sales);
            label5.Text = String.Format("Rs {0}.", payments);

            if (sales == (decimal)0 && payments == (decimal)0)
                label3.Text = "No transactions made.";
            else if (sales == payments)
                label3.Text = "Account clear.";
            else if (sales > payments)
                label3.Text = String.Format("Dues: Rs {0}.", sales - payments);
            else
                label3.Text = String.Format("Deposit: Rs {0}.", payments - sales);
        }

        private void PopulateAccountsGrid()
        {
            IEnumerable<Customer> cust;
            if (toolStripTextBox2.Text == "")
                cust = accountHandler.Customers;
            else
                cust = accountHandler.Filter(toolStripTextBox2.Text);
            foreach (var c in cust)
                Console.WriteLine("ID: {0}, Name: {1}, Phone: {2}", c.CustomerID, c.CustomerName, c.CustomerPhone);

            accountsGrid.DataSource = cust;

            //var custWithBal = accountHandler.GetBalance(toList, activityHandler, salesHandler);
            if (accountsGrid.Rows.Count > 0)
                accountsGrid.Rows[0].Selected = true;
        }

        private void InitializeMenu()
        {
            menuGrid.MultiSelect = false;
            toolStripTextBox1.TextChanged += new EventHandler(FilterMenuGrid);
            menuGrid.DataError += new DataGridViewDataErrorEventHandler(menuGrid_DataError);
            PopulateMenuGrid();
        }

        void menuGrid_DataError(object sender, DataGridViewDataErrorEventArgs e)
        {
            statusText.Text = e.Exception.Message;
            if (e.ColumnIndex == 0 || e.ColumnIndex == 2)
            {
                statusText.Text += String.Format(" The {0} column can only have numeric values.", e.ColumnIndex == 0 ? "DishID" : "DishPrice");
                menuGrid.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = menuGrid.Rows[e.RowIndex].Cells[e.ColumnIndex].DefaultNewRowValue;
            }
        }

        void FilterMenuGrid(object sender, EventArgs e)
        {
            PopulateMenuGrid();
        }

        private void PopulateMenuGrid()
        {
            IEnumerable<Dish> data;
            if (toolStripTextBox1.Text == "")
                data = dishesHandler.Dishes;
            else
                data = dishesHandler.Filter(toolStripTextBox1.Text);

            menuGrid.Rows.Clear();
            foreach (Dish d in data)
            {
                menuGrid.Rows.Add(new object [] { d.DishName, d.DishPrice });
            }
        }

        private void toolStripButton2_Click(object sender, EventArgs e)
        {
            if (!AreAllTablesClosed())
            {
                MessageBox.Show("Please close all tables before changing the menu.");
                return;
            }
            string item;
            decimal price;
            bool isMenuDirty = false;
            for (int i = 0; i < menuGrid.Rows.Count; ++i)
            {
                try
                {
                    item = menuGrid.Rows[i].Cells["DishName"].Value as string;
                    if (item == null)
                        continue;
                    try
                    {
                        price = (decimal)menuGrid.Rows[i].Cells["DishPrice"].Value;
                    }
                    catch (NullReferenceException)
                    {
                        menuGrid.Rows[i].Cells["DishName"].Selected = true;
                        price = Decimal.Parse(menuGrid.Rows[i].Cells["DishPrice"].Value as string);
                    }
                    catch (InvalidCastException)
                    {
                        try
                        {
                            price = Decimal.Parse(menuGrid.Rows[i].Cells["DishPrice"].Value as string);
                        }
                        catch (Exception x)
                        {
                            statusText.Text = x.Message;
                            return;
                        }
                    }
                    var v = from dish in dishesHandler.Dishes
                            where dish.DishName == item
                            select dish;
                    if (v.Count() == 0)
                    {
                        isMenuDirty = true;
                        dishesHandler.Add(item, price);
                    }
                    else if (v.First().DishPrice != price)
                    {
                        isMenuDirty = true;
                        v.First().DishPrice = price;
                    }
                }
                catch (ArgumentNullException) { continue; }
            }
            if (isMenuDirty)
            {
                dishesHandler.Save();
                PopulateMenuGrid();
                PopulateBillMenuGrid();
                AddColumnsToBillGrid();
            }
        }

        private void toolStripButton1_Click(object sender, EventArgs e)
        {
            PopulateMenuGrid();
        }

        private void toolStripButton3_Click(object sender, EventArgs e)
        {
            PopulateAccountsGrid();
        }

        private void toolStripButton4_Click(object sender, EventArgs e)
        {
            NewAccountDetails newAccnt = new NewAccountDetails();
            newAccnt.ShowDialog();
            if (!newAccnt.IsCancelled)
            {
                if (newAccnt.Phone == "")
                    accountHandler.Add(newAccnt.AccountName);
                else
                    accountHandler.Add(newAccnt.AccountName, newAccnt.Phone);
            }
            PopulateAccountsGrid();
        }

        private void toolStripButton3_Click_1(object sender, EventArgs e)
        {
            PopulateAccountsGrid();
        }

        private void toolStripButton5_Click(object sender, EventArgs e)
        {
            NewAccountActivity newAct = new NewAccountActivity();
            if (accountsGrid.SelectedRows.Count > 0)
                newAct.UserName = (accountsGrid.SelectedRows[0].Cells["CustomerName"].Value as string);
            newAct.ShowDialog();
            int custID;
            if (!newAct.IsCancelled)
            {
                try
                {
                    custID = accountHandler.Customers.First(C => C.CustomerName == newAct.UserName).CustomerID;
                }
                catch (Exception x)
                {
                    statusText.Text = x.Message;
                    return;
                }
                try
                {
                    activityHandler.Add(custID, newAct.BillNo == "" ? (int?)null : Int32.Parse(newAct.BillNo), Decimal.Parse(newAct.Amount), newAct.IsPayment, newAct.DatePicked);
                }
                catch (Exception x)
                {
                    statusText.Text = x.Message;
                    return;
                }
                PopulateActivitiesGrid(custID);
            }
        }

        private void toolStripButton3_Click_2(object sender, EventArgs e)
        {
            toolStripButton3_Click_1(sender, e);
        }

        private void toolStripButton4_Click_1(object sender, EventArgs e)
        {
            toolStripButton4_Click(sender, e);
        }

        private void toolStripButton7_Click_1(object sender, EventArgs e)
        {
            toolStripButton7_Click(sender, e);
        }

        private void toolStripButton8_Click_1(object sender, EventArgs e)
        {
            toolStripButton8_Click(sender, e);
        }

        private void toolStripButton6_Click(object sender, EventArgs e)
        {
            tabControl1.SelectedTab = tabControl1.TabPages[3];
        }

        private void optionsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ConfigOptions config = new ConfigOptions();
            config.ShowDialog();
            label10.Text = String.Format("Tax (@{0}%):", ConfigHandler.Configuration.TaxRate);
        }

        private void deleteItemToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (!AreAllTablesClosed())
            {
                MessageBox.Show("Please close all tables before changing the menu.");
                return;
            }
            if (menuGrid.SelectedRows.Count != 0)
            {
                string item;
                decimal price;
                for (int i = 0; i < menuGrid.SelectedRows.Count; ++i)
                {
                    try
                    {
                        item = menuGrid.SelectedRows[i].Cells["DishName"].Value as string;
                        if (item == null)
                            continue;
                        try
                        {
                            price = (decimal)menuGrid.SelectedRows[i].Cells["DishPrice"].Value;
                        }
                        catch (InvalidCastException)
                        {
                            try
                            {
                                price = Decimal.Parse(menuGrid.SelectedRows[i].Cells["DishPrice"].Value as string);
                            }
                            catch (Exception x)
                            {
                                statusText.Text = x.Message;
                                return;
                            }
                        }
                        var v = from dish in dishesHandler.Dishes
                                where dish.DishName == item
                                select dish;
                        dishesHandler.ListOfDishes.Remove(v.First());
                        menuGrid.Rows.RemoveAt(menuGrid.SelectedRows[i].Index);
                    }
                    catch (ArgumentException) { continue; }
                    
                }
                dishesHandler.Save();
                PopulateMenuGrid();
                PopulateBillMenuGrid();
                AddColumnsToBillGrid();
            }
        }

        private void billToolStripMenuItem_Click(object sender, EventArgs e)
        {
            return;
        }

        private void delCust_Click(object sender, EventArgs e)
        {
            if (accountsGrid.SelectedRows.Count > 0)
            {
                int custID = (int)accountsGrid[0, accountsGrid.SelectedRows[0].Index].Value;
                try
                {
                    accountHandler.Remove(custID);
                }
                catch (Exception x)
                {
                    statusText.Text = x.Message;
                }
                PopulateAccountsGrid();
            }

        }

        private void deleteToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (accountActivitiesGrid.SelectedRows.Count > 0)
            {
                int actID = (int)accountActivitiesGrid[0, accountActivitiesGrid.SelectedRows[0].Index].Value;
                int custID = (int)accountActivitiesGrid[1, accountActivitiesGrid.SelectedRows[0].Index].Value;
                activityHandler.Remove(actID);
                PopulateActivitiesGrid(custID);
            }
        }

        private void salesContext_Opening(object sender, CancelEventArgs e)
        {
            return;
        }

        private void deleteToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            if (salesGrid.SelectedRows.Count > 0)
            {
                //Get the SalesID of the sale to remove
                int id = (int)salesGrid[0, salesGrid.SelectedRows[0].Index].Value;

                //If the sale was a display quack, do nothing.
                var av = from sale in salesHandler.Sales
                         where sale.SalesID == id
                         select sale;
                if (av.Count() == 0)
                {
                    statusText.Text = "The listing is a ghost item, put up only for display continuity purposes.";
                    return;
                }

                //Retrieve all associated saledetails and remove them
                var saledetails = soldItemsHandler.Filter(id);
                DB.SoldItems.DeleteAllOnSubmit(saledetails);

                //Retrieve all activities that have this SalesID as an associated sale
                var accountactivities = from activity in activityHandler.Activities
                                        where activity.SalesID == id
                                        select activity;
                DB.Activities.DeleteAllOnSubmit(accountactivities);
                
                salesHandler.Remove(id);
                PopulateSalesGrid(false, null, "");
                PopulateActivitiesGrid(currentUserID);
                PopulateSalesDetailsGrid();

                //Mark the id as unused.
                if (!ConfigHandler.Configuration.UnusedSalesID.Contains(id))
                    ConfigHandler.Configuration.UnusedSalesID.Push(id);
                ConfigHandler.Configuration.Save();
            }
        }

        private void deleteSaleDetail_Click(object sender, EventArgs e)
        {
            if (salesDetailsGrid.SelectedRows.Count > 0)
            {
                int id = (int)salesDetailsGrid[5, salesDetailsGrid.SelectedRows[0].Index].Value;
                soldItemsHandler.Remove(id);
                PopulateSalesDetailsGrid();
            }
        }

        private void editCust_Click(object sender, EventArgs e)
        {
            Customer accnt;
            if (accountsGrid.SelectedRows.Count > 0)
            {
                accnt = accountHandler.Customers.First(C => C.CustomerID == (int)accountsGrid[0, accountsGrid.SelectedRows[0].Index].Value);
                NewAccountDetails editForm = new NewAccountDetails();
                editForm.AccountName = accnt.CustomerName;
                editForm.Phone = accnt.CustomerPhone;
                editForm.ShowDialog();
                if (!editForm.IsCancelled)
                {
                    accnt.CustomerName = editForm.AccountName;
                    accnt.CustomerPhone = editForm.Phone;
                    accountHandler.Save();
                    PopulateAccountsGrid();
                }
            }
        }

        private void logToolStripMenuItem_Click(object sender, EventArgs e)
        {
            LogViewer view = new LogViewer();
            view.Show();
        }

        private void accountsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            tabControl1.SelectedTab = tabControl1.TabPages[1];
        }

        private void billingToolStripMenuItem_Click(object sender, EventArgs e)
        {
            tabControl1.SelectedTab = tabControl1.TabPages[3];
        }

        private void newBillToolStripMenuItem_Click(object sender, EventArgs e)
        {
            tabControl1.SelectedTab = tabControl1.TabPages[0];
        }

        private void salesToolStripMenuItem_Click(object sender, EventArgs e)
        {
            tabControl1.SelectedTab = tabControl1.TabPages[2];
        }

        private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            AboutRestaurateur about = new AboutRestaurateur();
            about.ShowDialog();
        }

        private void InitBalance()
        {
            toolStripTextBox4.TextChanged += new EventHandler(toolStripTextBox4_TextChanged);
            numericUpDown2.Maximum = DateTime.Now.Year;
            comboBox2.SelectedIndex = DateTime.Now.Month - 1;
            numericUpDown2.Maximum = DateTime.Now.Year;
            numericUpDown2.Value = DateTime.Now.Year;
            checkBox1.Checked = true;
            PopulateBalanceGrid("");
        }

        void toolStripTextBox4_TextChanged(object sender, EventArgs e)
        {
            PopulateBalanceGrid(toolStripTextBox4.Text);
        }

        private void toolStripButton10_Click(object sender, EventArgs e)
        {
            AddXAction addXAction = new AddXAction();
            addXAction.ShowDialog();
            if (!addXAction.IsCancelled)
            {
                xActionHandler.List.TotalBalance += addXAction.Transaction.DepositAmount;
                xActionHandler.List.TotalBalance -= addXAction.Transaction.WithdrawAmount;
                addXAction.Transaction.ClosingBalance = xActionHandler.List.TotalBalance;
                xActionHandler.List.Transactions.Add(addXAction.Transaction);
                xActionHandler.Save();
                PopulateBalanceGrid("");
            }
        }

        XActionHandler xActionHandler = new XActionHandler();
        private void PopulateBalanceGrid(string FilterText)
        {
            balanceLabel.Text = String.Format("Rs {0}", xActionHandler.List.TotalBalance);
            IEnumerable<XAction> data;
            if (checkBox1.Checked)
            {
                if (comboBox2.SelectedIndex == -1)
                {
                    statusText.Text = "Please select a valid month in the drop-down box.";
                    checkBox1.Checked = false;
                }
                data = from transaction in xActionHandler.List.Transactions
                       where transaction.TransactionDate.Month == comboBox2.SelectedIndex + 1 && transaction.TransactionDate.Year == numericUpDown2.Value
                       select transaction;
            }
            else if (!String.IsNullOrEmpty(FilterText))
            {
                data = from transaction in xActionHandler.List.Transactions
                       where transaction.PayerName != null
                       where transaction.PayeeName.ToLower().IndexOf(FilterText.ToLower()) != -1 || transaction.PayerName.ToLower().IndexOf(FilterText.ToLower()) != -1
                       select transaction;
            }
            else
            {
                data = xActionHandler.List.Transactions.AsEnumerable();
            }
            balanceGrid.Rows.Clear();
            balanceGrid.Columns.Clear();
            balanceGrid.Columns.Add(new DataGridViewTextBoxColumn() { Name = "Transaction Date" });
            balanceGrid.Columns.Add(new DataGridViewTextBoxColumn() { Name = "Deposit (Rs)" });
            balanceGrid.Columns.Add(new DataGridViewTextBoxColumn() { Name = "Type" });
            balanceGrid.Columns.Add(new DataGridViewTextBoxColumn() { Name = "Cheque/DD Number" });
            balanceGrid.Columns.Add(new DataGridViewTextBoxColumn() { Name = "Party" });
            balanceGrid.Columns.Add(new DataGridViewTextBoxColumn() { Name = "Withdrawal (Rs)" });
            balanceGrid.Columns.Add(new DataGridViewTextBoxColumn() { Name = "Type" });
            balanceGrid.Columns.Add(new DataGridViewTextBoxColumn() { Name = "Cheque/DD Number" });
            balanceGrid.Columns.Add(new DataGridViewTextBoxColumn() { Name = "Party" });
            balanceGrid.Columns.Add(new DataGridViewTextBoxColumn() { Name = "Closing Balance" });

            foreach (var item in data)
            {
                DataGridViewRow row = new DataGridViewRow();
                row.Cells.Add(new DataGridViewTextBoxCell() { Value = item.TransactionDate.ToShortDateString() });
                row.Cells.Add(new DataGridViewTextBoxCell() { Value = item.DepositAmount.ToString() });
                row.Cells.Add(new DataGridViewTextBoxCell() { Value = item.DepositType.ToString() });
                row.Cells.Add(new DataGridViewTextBoxCell() { Value = item.DepositComment });
                row.Cells.Add(new DataGridViewTextBoxCell() { Value = item.PayerName });
                row.Cells.Add(new DataGridViewTextBoxCell() { Value = item.WithdrawAmount.ToString() });
                row.Cells.Add(new DataGridViewTextBoxCell() { Value = item.WithdrawType.ToString() });
                row.Cells.Add(new DataGridViewTextBoxCell() { Value = item.WithdrawComment });
                row.Cells.Add(new DataGridViewTextBoxCell() { Value = item.PayeeName });
                row.Cells.Add(new DataGridViewTextBoxCell() { Value = item.ClosingBalance });
                balanceGrid.Rows.Add(row);
            }
        }

        private void toolStripButton10_Click_1(object sender, EventArgs e)
        {
            toolStripButton10_Click(sender, e);
        }

        private void comboBox2_SelectedIndexChanged(object sender, EventArgs e)
        {
            PopulateBalanceGrid("");
        }

        private void numericUpDown2_ValueChanged(object sender, EventArgs e)
        {
            PopulateBalanceGrid("");
        }

        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {
            PopulateBalanceGrid("");
        }

        private void toolStripMenuItem1_Click(object sender, EventArgs e)
        {
            if (checkBox1.Checked)
            {
                statusText.Text = "Cannot delete transactions when filtering is enabled. Please uncheck the Filter box.";
                return;
            }
            if (balanceGrid.SelectedRows.Count > 0)
            {
                int index = balanceGrid.SelectedRows[0].Index;
                XAction toRemove = xActionHandler.List.Transactions.ElementAt(index);
                xActionHandler.List.TotalBalance -= toRemove.DepositAmount;
                xActionHandler.List.TotalBalance += toRemove.WithdrawAmount;
                xActionHandler.List.Transactions.RemoveAt(index);
                xActionHandler.Save();
                PopulateBalanceGrid("");
            }
        }

        private void toolStripButton7_Click_2(object sender, EventArgs e)
        {
            toolStripButton7_Click_1(sender, e);
        }

        private void toolStripButton9_Click_1(object sender, EventArgs e)
        {
            toolStripButton9_Click(sender, e);
        }

        private void toolStripButton8_Click_2(object sender, EventArgs e)
        {
            toolStripButton8_Click_1(sender, e);
        }

        private void toolStripButton11_Click(object sender, EventArgs e)
        {
            toolStripButton11.Checked = !toolStripButton11.Checked;
            if (toolStripButton11.Checked)
                PopulateSalesGrid(true, null, "");
            else
                PopulateSalesGrid(false, null, "");
        }

        private void billDate_ValueChanged(object sender, EventArgs e)
        {
            if (currentTable != -1)
            {
                PerTableBill bill = perTableBill[currentTable - 1];
                bill.BillDate = billDate.Value;
            }
        }

        private void billmenuFilter_TextChanged(object sender, EventArgs e)
        {
            PopulateBillMenuGrid();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (billGrid.Enabled)
            {
                if (listView1.SelectedItems.Count > 0)
                    billmenuGrid_CellDoubleClick(listView1.SelectedItems[0].Text, false);
                else if (listView1.Items.Count > 0)
                    billmenuGrid_CellDoubleClick(listView1.Items[0].Text, false);
                else
                    billmenuGrid_CellDoubleClick(billmenuFilter.Text, true);
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (billGrid.Enabled)
            {
                billmenuFilter.Text = "";
                billGrid.Select();
            }
        }

        private void toolStripButton12_Click(object sender, EventArgs e)
        {
            OpenBillNo openBill = new OpenBillNo();
            openBill.ShowDialog();
            if (openBill.DialogResult == DialogResult.OK)
                PopulateSalesGrid(false, openBill.SalesID, "");
        }

        private void toolStripButton7_Click_3(object sender, EventArgs e)
        {
            toolStripButton7_Click_2(sender, e);
        }

        private void toolStripButton9_Click_2(object sender, EventArgs e)
        {
            toolStripButton9_Click_1(sender, e);
        }

        private void toolStripButton8_Click_3(object sender, EventArgs e)
        {
            toolStripButton8_Click_2(sender, e);
        }

        private string accountName = "";
        private bool updateBillNo = false;
        private void editBillToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (salesGrid.SelectedRows.Count > 0)
            {
                int tableIndex = 0;
                for (int i = 0; i < perTableBill.Length; ++i)
                    if (perTableBill[i] == null)
                    {
                        tableIndex = i;
                        break;
                    }
                PerTableBill Bill = new PerTableBill(tableIndex + 1);
                Bill.IsSaved = false;
                perTableBill[tableIndex] = Bill;

                try
                {
                    Bill.BillNo = (int)salesGrid.SelectedRows[0].Cells[0].Value;
                    Bill.BillDate = (DateTime)salesGrid.SelectedRows[0].Cells[1].Value;
                    Bill.Account = salesGrid.SelectedRows[0].Cells[3].Value as string;

                    if (accountName != "")
                    {
                        if (Bill.Account.ToLower() != accountName.ToLower())
                            Bill.Account = accountName;
                        accountName = "";
                    }

                    decimal amount = (decimal)0;
                    int i = 0;

                    var v = soldItemsHandler.Filter(Bill.BillNo);
                    if (v.Count() > 0)
                    {
                        foreach (var item in v)
                        {
                            ABill aB = new ABill();
                            aB.Item = item.ItemName;
                            aB.Quantity = (decimal)item.Quantity;
                            aB.Amount = item.Price;
                            aB.Price = aB.Amount / aB.Quantity;

                            i++;
                            amount += aB.Amount;

                            Bill.Bill.Add(aB);
                            Bill.DirtySoldItemIDs.Add(item.SoldItemsID);
                        }
                    }
                    else
                    {
                        salesHandler.Remove(Bill.BillNo);
                    }
                    if (updateBillNo)
                    {
                        if ((from sale in salesHandler.Sales where sale.SalesID == Bill.BillNo select sale).Count() != 0)
                            salesHandler.Remove(Bill.BillNo);
                        Bill.BillNo = ConfigHandler.Configuration.GetNewSalesID();
                        updateBillNo = false;
                    }
                    Bill.TotalWithoutTax = amount;
                    Bill.NoOfItems = i;
                }
                catch (Exception x)
                {
                    statusText.Text = x.Message;
                }

                Button btn = billButtonsLayoutPanel.Controls[tableIndex] as Button;
                btn.Text = btn.Text.Substring(0, btn.Text.IndexOf("*"));
                b_Click(btn, new EventArgs());
                tabControl1.SelectedIndex = 3;
                updateBillNo = false;
            }
        }

        private void backupToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                BackupHandler.Backup(DB, dishesHandler);
                statusText.Text = String.Format("Databases backed up successfully to Desktop\\Restaurateur Data Backup\\{0}", DateTime.Now.ToLongDateString());
            }
            catch (Exception x)
            {
                statusText.Text = x.Message;
            }
        }

        private void salesToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            DirectoryInfo dir = GetDirectory();
            if (dir != null)
            {
                try
                {
                    BackupDB db = BackupHandler.ViewBackupDB(dir.FullName);
                    DB.Sales.InsertAllOnSubmit(db.sales.AsEnumerable());
                    DB.SubmitChanges();
                    var max = DB.Sales.Max(S => S.SalesID);
                    if (max > ConfigHandler.Configuration.SalesID)
                    {
                        ConfigHandler.Configuration.SalesID = max;
                        ConfigHandler.Configuration.Save();
                    }
                    statusText.Text = db.sales.Count.ToString() + " sale records imported successfully.";
                    ConfigHandler.Configuration.UnusedSalesID.Clear();
                    ConfigHandler.Configuration.Save();
                    PopulateSalesGrid(false, null, "");
                    MessageBox.Show("Records imported successfully. Please restart before the changes will take effect.");
                }
                catch (Exception x)
                {
                    MessageBox.Show(x.Message);
                }
            }
        }

        private DirectoryInfo GetDirectory()
        {
            FolderBrowserDialog folders = new FolderBrowserDialog();
            folders.RootFolder = Environment.SpecialFolder.Desktop;
            folders.Description = "Please select the folder containing backups:";
            if (Directory.Exists(Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\Restaurateur Data Backup"))
                folders.SelectedPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\Restaurateur Data Backup";
            folders.ShowNewFolderButton = false;
            if (folders.ShowDialog() == DialogResult.Cancel)
                return null;
            else
                return new DirectoryInfo(folders.SelectedPath);
        }

        private void salesDetailsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            DirectoryInfo dir = GetDirectory();
            if (dir != null)
            {
                try
                {
                    BackupDB db = BackupHandler.ViewBackupDB(dir.FullName);
                    DB.SoldItems.InsertAllOnSubmit(db.solditems.AsEnumerable());
                    DB.SubmitChanges();
                    var max = DB.SoldItems.Max(S => S.SoldItemsID);
                    if (max > ConfigHandler.Configuration.SoldItemsID)
                    {
                        ConfigHandler.Configuration.SoldItemsID = max;
                        ConfigHandler.Configuration.Save();
                    }
                    statusText.Text = db.solditems.Count.ToString() + " sale detail records imported successfully.";
                    PopulateSalesDetailsGrid();
                    MessageBox.Show("Records imported successfully. Please restart before the changes will take effect.");
                }
                catch (Exception x)
                {
                    MessageBox.Show(x.Message);
                }
            }
        }

        private void accountsToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            DirectoryInfo dir = GetDirectory();
            if (dir != null)
            {
                try
                {
                    BackupDB db = BackupHandler.ViewBackupDB(dir.FullName);
                    DB.Customers.InsertAllOnSubmit(db.accounts.AsEnumerable());
                    DB.SubmitChanges();
                    statusText.Text = db.accounts.Count.ToString() + " account records imported successfully.";
                    PopulateAccountsGrid();
                    MessageBox.Show("Records imported successfully. Please restart before the changes will take effect.");
                }
                catch (Exception x)
                {
                    MessageBox.Show(x.Message);
                }
            }
        }

        private void activitiesToolStripMenuItem_Click(object sender, EventArgs e)
        {
            DirectoryInfo dir = GetDirectory();
            if (dir != null)
            {
                try
                {
                    BackupDB db = BackupHandler.ViewBackupDB(dir.FullName);
                    DB.Activities.InsertAllOnSubmit(db.activities.AsEnumerable());
                    DB.SubmitChanges();
                    statusText.Text = db.activities.Count.ToString() + " activity records imported successfully.";
                    PopulateActivitiesGrid(currentUserID);
                    MessageBox.Show("Records imported successfully. Please restart before the changes will take effect.");
                }
                catch (Exception x)
                {
                    MessageBox.Show(x.Message);
                }
            }
        }

        private void menuToolStripMenuItem_Click(object sender, EventArgs e)
        {
            DirectoryInfo dir = GetDirectory();
            if (dir != null)
            {
                try
                {
                    FileInfo[] menu = dir.GetFiles("RestaurateurMenu.menu");
                    if (menu.Length == 0)
                        throw new Exception("Could not find file RestaurateurMenu.menu");
                    menu[0].CopyTo(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + "\\Restaurateur\\RestaurateurMenu.menu", true);
                    statusText.Text = "Menu records imported successfully.";
                    MessageBox.Show("Records imported successfully. Please restart before the changes will take effect.");
                }
                catch (Exception x)
                {
                    MessageBox.Show(x.Message);
                }
            }
        }

        private void balanceToolStripMenuItem_Click(object sender, EventArgs e)
        {
            DirectoryInfo dir = GetDirectory();
            if (dir != null)
            {
                try
                {
                    FileInfo[] menu = dir.GetFiles("RestaurateurMenu.balance");
                    if (menu.Length == 0)
                        throw new Exception("Could not find file RestaurateurMenu.balance");
                    menu[0].CopyTo(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + "\\Restaurateur\\RestaurateurMenu.balance", true);
                    statusText.Text = "Balance and transaction records imported successfully.";
                    MessageBox.Show("Records imported successfully. Please restart before the changes will take effect.");
                }
                catch (Exception x)
                {
                    MessageBox.Show(x.Message);
                }
            }
        }

        private void configurationToolStripMenuItem_Click(object sender, EventArgs e)
        {
            DirectoryInfo dir = GetDirectory();
            if (dir != null)
            {
                try
                {
                    FileInfo[] menu = dir.GetFiles("RestaurateurMenu.config");
                    if (menu.Length == 0)
                        throw new Exception("Could not find file RestaurateurMenu.config");
                    menu[0].CopyTo(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + "\\Restaurateur\\RestaurateurMenu.config", true);
                    statusText.Text = "Configuration records imported successfully.";
                    MessageBox.Show("Configuration settings imported successfully. Please restart before the changes will take effect.");
                }
                catch (Exception x)
                {
                    MessageBox.Show(x.Message);
                }
            }
        }

        private void resetDatabaseToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("Proceeding will delete all data. Sure?", "WARNING: This can delete all data!", MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2) == DialogResult.Yes)
            {
                try
                {
                    BackupHandler.ResetDatabase(DB);
                    MessageBox.Show("Database reset. Application needs to be restarted now.");
                    this.Close();
                }
                catch (Exception x)
                {
                    statusText.Text = x.Message;
                }
            }
        }

        private void toolStripButton7_Click_4(object sender, EventArgs e)
        {
            toolStripButton7_Click_3(sender, e);
        }

        private void toolStripButton9_Click_3(object sender, EventArgs e)
        {
            toolStripButton9_Click_2(sender, e);
        }

        private void toolStripButton8_Click_4(object sender, EventArgs e)
        {
            toolStripButton8_Click_3(sender, e);
        }

        private void toolStripTextBox3_Click(object sender, EventArgs e)
        {
            return;
        }

        private void searchCreditedSalesToolStripMenuItem_Click(object sender, EventArgs e)
        {
            toolStripTextBox3_TextChanged(null, null);
        }

        private bool AreAllTablesClosed()
        {
            for (int i = 0; i < ConfigHandler.Configuration.NoOfTables; ++i)
                if (perTableBill[i] != null)
                    return false;
            return true;
        }

        private void toolStripTextBox4_Click(object sender, EventArgs e)
        {
            return;
        }

        private void textBox3_TextChanged(object sender, EventArgs e)
        {
            if (textBox3.Text == "")
            {
                textBox3.Text = "Click here to search for sales credited to accounts...";
                PopulateSalesGrid(false, null, "");
            }
            else if (textBox3.Text == "Click here to search for sales credited to accounts...")
            {
                return;
            }
            else
                PopulateSalesGrid(false, null, textBox3.Text);
        }

        private void toolStripMenuItem2_Click(object sender, EventArgs e)
        {
            if (billGrid.SelectedRows.Count > 0)
            {
                try
                {
                    billGrid.Rows.Remove(billGrid.SelectedRows[0]);
                    if (billGrid.Rows.Count <= 1)
                        billGrid_CellEndEdit(null, null);
                    else
                        billGrid_CellEndEdit(billGrid, new DataGridViewCellEventArgs(0, 0));
                }
                catch (InvalidOperationException x)
                {
                    statusText.Text = x.Message;
                }
            }
        }

        private void toolStripButton5_Click_1(object sender, EventArgs e)
        {
            toolStripButton5_Click(sender, e);
        }

        private void configViewerToolStripMenuItem_Click(object sender, EventArgs e)
        {
            LogViewer viweer = new LogViewer(true);
            viweer.Show();
        }

        private void toolStripButton7_Click_5(object sender, EventArgs e)
        {
            toolStripButton7_Click_4(sender, e);
        }

        private void toolStripButton9_Click_4(object sender, EventArgs e)
        {
            toolStripButton9_Click_3(sender, e);
        }

        private void toolStripButton8_Click_5(object sender, EventArgs e)
        {
            toolStripButton8_Click_4(sender, e);
        }

        private void toolStripButton7_Click_6(object sender, EventArgs e)
        {
            toolStripButton7_Click_5(sender, e);
        }

        private void toolStripButton9_Click_5(object sender, EventArgs e)
        {
            toolStripButton9_Click_4(sender, e);
        }

        private void toolStripButton8_Click_6(object sender, EventArgs e)
        {
            toolStripButton8_Click_5(sender, e);
        }

        private void balanceToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            tabControl1.SelectedIndex = 4;
        }

        public void toolStripMenuItem3_Click(object sender, EventArgs e)
        {
            ConfigHandler.Configuration.SoldItemsID = soldItemsHandler.SoldItems.Max(D => D.SoldItemsID);
            ConfigHandler.Configuration.SalesID = salesHandler.Sales.Max(D => D.SalesID);
            ConfigHandler.Configuration.UnusedSalesID.Clear();
            ConfigHandler.Configuration.Save();
        }

        private void updateBillNoToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (salesGrid.SelectedRows.Count > 0)
            {
                updateBillNo = true;
                editBillToolStripMenuItem_Click(null, null);
            }
        }

        private void resetIDsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("This will reset the bill No. Continue?", "WARNING: This will reset bill number.", MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1) == DialogResult.OK)
            {
                ConfigHandler.Configuration.SalesID = -1;
                ConfigHandler.Configuration.SoldItemsID = -1;
                ConfigHandler.Configuration.UnusedSalesID.Clear();
                ConfigHandler.Configuration.Save();
            }
        }

        private void toolStripMenuItem4_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("This will unregister the application; key will be required on next restart. Continue?", "WARNING: This will reset registration.", MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1) == DialogResult.OK)
            {
                ConfigHandler.Configuration.RegistrationKey = "";
                ConfigHandler.Configuration.Save();
            }
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            if (MainForm.creatorForm != null)
                MainForm.creatorForm.Hide();
        }

        public void SetStatusText(string msg)
        {
            statusText.Text = msg;
        }

        private void allItemsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            accountsToolStripMenuItem1_Click(null, null);
            activitiesToolStripMenuItem_Click(null, null);
            salesToolStripMenuItem1_Click(null, null);
            salesDetailsToolStripMenuItem_Click(null, null);
            menuToolStripMenuItem_Click(null, null);
            balanceToolStripMenuItem_Click(null, null);
            configurationToolStripMenuItem_Click(null, null);
        }

        private void toolStripMenuItem5_Click(object sender, EventArgs e)
        {
            if (salesGrid.Rows.Count > 0)
            {
                PrintBill print = new PrintBill();
                print.AddToPrint(print.CenterLine("Sales", 35));
                print.AddToPrint("Bill No    Date    Amount  Account ");
                print.AddToPrint("-----------------------------------");
                decimal totalSales = (decimal)0, creditSales = (decimal)0, cashSales = (decimal)0;
                for (int i = 0; i < salesGrid.Rows.Count; ++i)
                {
                    string row = "";
                    row += print.LeftLine(((int)salesGrid[0, i].Value).ToString(), 8);
                    row += print.RightLine(((DateTime)salesGrid[1, i].Value).ToShortDateString(), 10) + " ";
                    row += print.LeftLine(((decimal)salesGrid[2, i].Value).ToString(), 6);
                    row += print.CenterLine(salesGrid[3, i].Value as string, 10);
                    print.AddToPrint(row);

                    totalSales += (decimal)salesGrid[2, i].Value;
                    if (!String.IsNullOrEmpty(salesGrid[3, i].Value as string))
                        creditSales += (decimal)salesGrid[2, i].Value;
                }
                cashSales = totalSales - creditSales;

                print.AddToPrint("-----------------------------------");
                print.AddToPrint(print.LeftLine("Total Sales: Rs " + totalSales.ToString() + ".", 35));
                print.AddToPrint(print.LeftLine("   Cash Sales: Rs " + cashSales.ToString() + ".", 35));
                print.AddToPrint(print.LeftLine("   Credit Sales: Rs " + creditSales.ToString() + ".", 35));

                print.Print();
            }
        }

        private void printToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (accountActivitiesGrid.Rows.Count > 0)
            {
                PrintBill print = new PrintBill();
                int custID = (int)accountActivitiesGrid.Rows[0].Cells[1].Value;
                var custName = accountHandler.Customers.First(C => C.CustomerID == custID).CustomerName;
                print.AddToPrint(print.CenterLine("Activities on account: " + custName, 35));
                print.AddToPrint(print.Repeat(" ", 35));
                print.AddToPrint("Bill No    Date    Purchase Payment");
                print.AddToPrint("-----------------------------------");
                decimal totalPurchases = (decimal)0, totalPayments = (decimal)0, balance = (decimal)0;
                for (int i = 0; i < accountActivitiesGrid.Rows.Count; ++i)
                {
                    string row = "";
                    row += print.LeftLine(((int)accountActivitiesGrid[3, i].Value).ToString(), 8);
                    row += print.RightLine(((DateTime)accountActivitiesGrid[2, i].Value).ToShortDateString(), 10) + " ";
                    
                    decimal? purchase = accountActivitiesGrid[4, i].Value as decimal?;
                    row += print.CenterLine(purchase.HasValue ? purchase.Value.ToString() : "", 8);
                    totalPurchases += purchase.HasValue ? purchase.Value : (decimal)0;

                    decimal? payment = accountActivitiesGrid[5, i].Value as decimal?;
                    row += print.CenterLine(payment.HasValue ? payment.Value.ToString() : "", 8);
                    totalPayments += payment.HasValue ? payment.Value : (decimal)0;

                    print.AddToPrint(row);
                }

                print.AddToPrint("-----------------------------------");
                print.AddToPrint(print.LeftLine("Total purchases: Rs " + totalPurchases.ToString() + ".", 35));
                print.AddToPrint(print.LeftLine("Total payments: Rs " + totalPayments.ToString() + ".", 35));

                balance = totalPurchases - totalPayments;
                if (balance == (decimal)0)
                    print.AddToPrint(print.LeftLine("   Account clear.", 35));
                else if (balance > (decimal)0)
                    print.AddToPrint(print.LeftLine("   Dues: Rs " + balance.ToString() + ".", 35));
                else
                    print.AddToPrint(print.LeftLine("   Deposit: Rs " + ((decimal)-1 * balance).ToString() + ".", 35));

                print.Print();
            }
        }

        private void toolStripMenuItem6_Click(object sender, EventArgs e)
        {
            if (balanceGrid.Rows.Count > 0)
            {
                PrintBill print = new PrintBill();
                print.AddToPrint(print.CenterLine("Deposits", 35));
                print.AddToPrint("   Date    Amount   Party   Balance");
                print.AddToPrint("-----------------------------------");
                for (int i = 0; i < balanceGrid.Rows.Count; ++i)
                {
                    if ((balanceGrid[1, i].Value as string) == "0")
                        continue;
                    string row = "";
                    row += print.LeftLine(balanceGrid[0, i].Value as string, 10);
                    row += print.CenterLine(balanceGrid[1, i].Value as string, 7);
                    row += print.CenterLine(balanceGrid[4, i].Value as string, 11);
                    row += print.CenterLine(((decimal)balanceGrid[9, i].Value).ToString(), 7);
                    print.AddToPrint(row);

                    string number = balanceGrid[3, i].Value as string;
                    if (!String.IsNullOrEmpty(number))
                    {
                        if (number.ToUpper() != number.ToLower())
                            print.AddToPrint(print.LeftLine(number, 35));
                        else
                            print.AddToPrint(print.LeftLine("Cheque/DD No: " + number, 35));
                    }
                    print.AddToPrint(print.Repeat(" ", 35));
                }
                print.Print();
            }
        }

        private void toolStripMenuItem7_Click(object sender, EventArgs e)
        {
            if (balanceGrid.Rows.Count > 0)
            {
                PrintBill print = new PrintBill();
                print.AddToPrint(print.CenterLine("Withdrawals", 35));
                print.AddToPrint("   Date    Amount   Party   Balance");
                print.AddToPrint("-----------------------------------");
                for (int i = 0; i < balanceGrid.Rows.Count; ++i)
                {
                    if ((balanceGrid[5, i].Value as string) == "0")
                        continue;
                    string row = "";
                    row += print.LeftLine(balanceGrid[0, i].Value as string, 10);
                    row += print.CenterLine(balanceGrid[5, i].Value as string, 7);
                    row += print.CenterLine(balanceGrid[8, i].Value as string, 11);
                    row += print.CenterLine(((decimal)balanceGrid[9, i].Value).ToString(), 7);
                    print.AddToPrint(row);

                    string number = balanceGrid[7, i].Value as string;
                    if (!String.IsNullOrEmpty(number))
                    {
                        if (number.ToUpper() != number.ToLower())
                            print.AddToPrint(print.LeftLine(number, 35));
                        else
                            print.AddToPrint(print.LeftLine("Cheque/DD No: " + number, 35));
                    }
                    print.AddToPrint(print.Repeat(" ", 35));
                }
                print.Print();
            }
        }

        private void toolStripMenuItem8_Click(object sender, EventArgs e)
        {
            SaveFileDialog saver = new SaveFileDialog();
            saver.AddExtension = true;
            saver.CreatePrompt = true;
            saver.DefaultExt = "txt";
            saver.Filter = "Text files (*.txt) | *.txt";
            saver.OverwritePrompt = true;
            saver.SupportMultiDottedExtensions = true;
            saver.Title = "Save menu as...";
            saver.ValidateNames = true;
            saver.RestoreDirectory = true;
            if (saver.ShowDialog() != DialogResult.Cancel)
            {
                try
                {
                    BackupHandler.ExportMenu(saver.FileName, dishesHandler);
                    statusText.Text = "Menu exported successfully to " + saver.FileName;
                }
                catch (Exception x)
                {
                    statusText.Text = x.Message;
                }
            }
        }

        private void exportCustomerDatabaseToolStripMenuItem_Click(object sender, EventArgs e)
        {
            SaveFileDialog saver = new SaveFileDialog();
            saver.AddExtension = true;
            saver.CreatePrompt = true;
            saver.DefaultExt = "txt";
            saver.Filter = "Text files (*.txt) | *.txt";
            saver.OverwritePrompt = true;
            saver.SupportMultiDottedExtensions = true;
            saver.Title = "Save menu as...";
            saver.ValidateNames = true;
            saver.RestoreDirectory = true;
            if (saver.ShowDialog() != DialogResult.Cancel)
            {
                try
                {
                    BackupHandler.ExportCustAsText(saver.FileName, accountHandler.Customers);
                    statusText.Text = "Customer database exported successfully to " + saver.FileName;
                }
                catch (Exception x)
                {
                    statusText.Text = x.Message;
                }
            }
        }

        private void toolStripMenuItem9_Click(object sender, EventArgs e)
        {
            SaveFileDialog saver = new SaveFileDialog();
            saver.AddExtension = true;
            saver.CreatePrompt = true;
            saver.DefaultExt = "txt";
            saver.Filter = "Text files (*.txt) | *.txt";
            saver.OverwritePrompt = true;
            saver.SupportMultiDottedExtensions = true;
            saver.Title = "Save menu as...";
            saver.ValidateNames = true;
            saver.RestoreDirectory = true;
            if (saver.ShowDialog() != DialogResult.Cancel)
            {
                try
                {
                    BackupHandler.ExportSaleAsText(saver.FileName, salesHandler.Sales);
                    statusText.Text = "Sales records exported successfully to " + saver.FileName;
                }
                catch (Exception x)
                {
                    statusText.Text = x.Message;
                }
            }
        }

        private void exportTransactionsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            SaveFileDialog saver = new SaveFileDialog();
            saver.AddExtension = true;
            saver.CreatePrompt = true;
            saver.DefaultExt = "txt";
            saver.Filter = "Text files (*.txt) | *.txt";
            saver.OverwritePrompt = true;
            saver.SupportMultiDottedExtensions = true;
            saver.Title = "Save menu as...";
            saver.ValidateNames = true;
            saver.RestoreDirectory = true;
            if (saver.ShowDialog() != DialogResult.Cancel)
            {
                try
                {
                    BackupHandler.ExportTransactionsAsText(saver.FileName, xActionHandler.List.Transactions);
                    statusText.Text = "Transactions list exported successfully to " + saver.FileName;
                }
                catch (Exception x)
                {
                    statusText.Text = x.Message;
                }
            }
        }

        private void normalizeSalesToolStripMenuItem_Click(object sender, EventArgs e)
        {
            foreach (var v in DB.Sales)
            {
                if (!String.IsNullOrEmpty(v.Account))
                    v.Account = v.Account.ToLower();
            }
            DB.SubmitChanges();
            PopulateSalesGrid(false, null, "");
        }

        private void normalizeAccountsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            foreach (var v in DB.Customers)
            {
                v.CustomerName = v.CustomerName.ToLower();
            }
            DB.SubmitChanges();
            PopulateAccountsGrid();
        }

        private void editBillToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            if (accountActivitiesGrid.SelectedRows.Count > 0)
            {
                PopulateSalesGrid(false, (int)accountActivitiesGrid.SelectedRows[0].Cells[3].Value, "");
                salesGrid.Rows[0].Selected = true;
                accountName = accountHandler.Customers.First(C => C.CustomerID == (int)accountActivitiesGrid.SelectedRows[0].Cells[1].Value).CustomerName;
                activityHandler.Remove((int)accountActivitiesGrid.SelectedRows[0].Cells[0].Value);
                editBillToolStripMenuItem_Click(null, null);
                PopulateActivitiesGrid(currentUserID);
                PopulateSalesGrid(false, null, "");
            }
        }

        private void printToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            if (salesDetailsGrid.SelectedRows.Count > 0)
                doubleClick_salesDetailsGrid(null, null);
        }

        private void printSingleBillToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (accountActivitiesGrid.SelectedRows.Count > 0)
                salesDetailsGrid_DoubleClick(null, null);
        }

        private void syncSalesActivitiesToolStripMenuItem_Click(object sender, EventArgs e)
        {
            foreach (var v in DB.Sales)
            {
                if (!String.IsNullOrEmpty(v.Account))
                {
                    int custID;
                    try
                    {
                        custID = accountHandler.Customers.First(C => C.CustomerName.ToLower() == v.Account.ToLower()).CustomerID;
                    }
                    catch
                    {
                        custID = accountHandler.Add(v.Account);
                    }
                    try
                    {
                        var a = activityHandler.Activities.First(A => A.SalesID == v.SalesID);
                    }
                    catch
                    {
                        activityHandler.Add(custID, v.SalesID, v.Amount, false, v.Date);
                    }
                }
            }
        }

        private void definitionsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            MemoryStream ms = new MemoryStream();
            TextWriter tw = new StreamWriter(ms);

            tw.WriteLine("SQL Logs - View SQL quereies issued against the database.\r\n");
            tw.WriteLine("Config viewer - View the current configuration of the software.\r\n");
            tw.WriteLine("Reset IDs - Resets the SalesID and SalesDetailsID to zero.\r\n");
            tw.WriteLine("Update IDs - Updates the IDs to max(SalesID) and max(SalesDetailsID) respectively.\r\n");
            tw.WriteLine("Reset database - Deletes all data from database.\r\n");
            tw.WriteLine("Backup database - Backs up the database to Desktop\\Restaurateur Data Backup\\<Today's Date>.\r\n");
            tw.WriteLine("Export sales - Exports the sales listings as a text file.\r\n");
            tw.WriteLine("Export menu - Exports the menu entries as a text file.\r\n");
            tw.WriteLine("Export transactions - Exports the transactions as a text file.\r\n");
            tw.WriteLine("Export Accounts Info - Export the customer database (not their sales info) as a text file.\r\n");
            tw.WriteLine("Normalize sales - Changes account names of sales credited to accounts to lowercase.\r\n");
            tw.WriteLine("Normalize accounts - Converts account names of customers to lowercase.\r\n");
            tw.WriteLine("Sync sales/activities - Synchronizes the sales and activities databases so that all sales credited to accounts also show up as account activities.\r\n");
            tw.WriteLine("Unregister - Deletes the registration info of the software. If the software had a backup run that backed up the reistration info previously, it will pick that up in the next run. Else it needs to be reistered on the next run.\r\n");
            tw.Close();

            byte[] buffer = ms.GetBuffer();

            LogViewer help = new LogViewer(buffer);
            help.Text = "Definitions of technical terms...";
            help.Show();
        }

        private void mergeToToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (accountsGrid.SelectedRows.Count > 0)
            {
                var currentID = (int)accountsGrid.SelectedRows[0].Cells[0].Value;
                var questionForm = new OpenBillNo("Merge with account:", "Account number:");
                questionForm.ShowDialog();
                if (questionForm.DialogResult == DialogResult.OK)
                {
                    var targetID = questionForm.SalesID;
                    string targetCustName, currentCustName;
                    try
                    {
                        targetCustName = DB.Customers.First(C => C.CustomerID == targetID).CustomerName;
                        currentCustName = DB.Customers.First(C => C.CustomerID == currentID).CustomerName;
                        if (MessageBox.Show(String.Format("Merge all activities of {0} to {1}?", currentCustName, targetCustName), "Merge?", MessageBoxButtons.OKCancel) != DialogResult.OK)
                            return;
                    }
                    catch
                    {
                        MessageBox.Show(String.Format("Account number {0} does not exist.", targetID));
                        return;
                    }
                    if (currentID == targetID)
                    {
                        statusText.Text = "Target account number same as current one; no action taken.";
                        return;
                    }
                    var allSalesOfCurrentID = activityHandler.Filter(currentID);
                    foreach (var sale in allSalesOfCurrentID)
                        sale.CustID = targetID;
                    DB.SubmitChanges();
                    if (MessageBox.Show(String.Format("Delete account {0}?", currentCustName), "Delete account?", MessageBoxButtons.OKCancel) == DialogResult.OK)
                        accountHandler.Remove(currentID);
                    PopulateAccountsGrid();
                    PopulateActivitiesGrid(currentID);
                }
            }
        }

        private void reassignActivityToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (accountActivitiesGrid.SelectedRows.Count > 0)
            {
                var currentID = (int)accountActivitiesGrid.SelectedRows[0].Cells[1].Value;
                var questionForm = new OpenBillNo("Assign sale to account:", "Account number:");
                questionForm.ShowDialog();
                if (questionForm.DialogResult == DialogResult.OK)
                {
                    var targetID = questionForm.SalesID;
                    try
                    {
                        string targetCustName = DB.Customers.First(C => C.CustomerID == targetID).CustomerName;
                        if (MessageBox.Show(String.Format("Assign sale to {0}?", targetCustName), "Reassign?", MessageBoxButtons.OKCancel) != DialogResult.OK)
                            return;
                    }
                    catch
                    {
                        MessageBox.Show(String.Format("Account number {0} does not exist.", targetID));
                        return;
                    }
                    if (currentID == targetID)
                    {
                        statusText.Text = "Target account number same as current one; no action taken.";
                        return;
                    }
                    DB.Activities.First(A => A.ActivityID == (int)accountActivitiesGrid.SelectedRows[0].Cells[0].Value).CustID = targetID;
                    DB.SubmitChanges();
                    PopulateActivitiesGrid(currentID);
                }
            }
        }
    }
}
